﻿/*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
 *~*  www.PBDesk.com 2010/2011                                                      
 *~*  
 *~*  Project : PBDesk.Utilities                        Namespace : PBDesk.Utilities
 *~*  File : StringExtensionMethods.cs                  Class : StringExtensionMethods
 *~*  
 *~*  Author : Pinal Bhatt (pinal.bhatt@PBDesk.com)
 *~*  Version History
 *~*            Ver. 1.0     Date 12-Oct-2010       Pinal Bhatt
 *~*            Ver. 2.0     Date 21-Jun-2011       Pinal Bhatt
 *~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*/

using System.Text.RegularExpressions;
using System.ComponentModel;
using System;

namespace PBDesk.Utilities
{
    /// <summary>
    /// Static Class containing Extension Methods for strings.
    /// Extending System.String functionalities
    /// </summary>
    public static class StringExtensions
    {


        /// <summary>
        /// Converts invoking string object to Type T and returns defaultValue if conversion fails
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strValue"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T As<T>(this string strValue, T defaultValue)
        {
            if (defaultValue == null)
            {
                defaultValue = default(T);
            }
            T output = defaultValue;
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
            if (converter != null)
            {
                try
                {
                    output = (T)converter.ConvertFromString(strValue);
                }
                catch
                {
                    output = defaultValue;
                }
            }
            return output;
        }

        /// <summary>
        /// Converts invoking string object to Type T and throws exception if conversion fails
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strValue"></param>
        /// <returns></returns>
        public static T As<T>(this string strValue)
        {
            T output = default(T);
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
            if (converter != null)
            {
                try
                {
                    output = (T)converter.ConvertFromString(strValue);
                }
                catch (NotSupportedException ex1)
                {
                    throw ex1;
                }
                catch (Exception ex)
                {
                    throw new Exception("Error in String.As() extension Method. Invalid Conversion.", ex);
                }
            }
            else
            {
                throw new NotSupportedException("Error in String.As(). Converter for specified type T is not available.");
            }
            return output;
        }

        /// <summary>
        /// Tries converting invoking string object to type T and returns true if success else returns false.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strValue"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool TryParse<T>(this string strValue, out T result)
        {
            bool success = false;
            result = default(T);
            try
            {
                result = strValue.As<T>();
                success = true;
            }
            catch
            {
                success = false;
            }
            return success;
        }

        /// <summary>
        /// Indicates whether invoking string object is null or not.
        /// </summary>
        /// <param name="inputString"></param>
        /// <returns>True, if string is null else returns false</returns>
        public static bool IsNull(this string inputString)
        {
            return (inputString == null);
        }

        /// <summary>
        /// Indicates whether invoking string object is null or not.
        /// </summary>
        /// <param name="inputString"></param>
        /// <returns>True, if string is not null else returns false</returns>
        public static bool IsNotNull(this string inputString)
        {
            return (inputString != null);
        }

        /// <summary>
        /// Indicates whether invoking string object is null or an empty string.
        /// </summary>
        /// <param name="inputstr"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string inputstr)
        {
            return string.IsNullOrEmpty(inputstr);
        }

        /// <summary>
        /// Indicates whether invoking string object is not null and not an empty string.
        /// </summary>
        /// <param name="inputString"></param>
        /// <returns></returns>
        public static bool IsNotNullAndNotEmpty(this string inputString)
        {
            return !string.IsNullOrEmpty(inputString);
        }


        /// <summary>
        /// Returns true if invoking string matches with regex pattern
        /// </summary>
        /// <param name="original"></param>
        /// <param name="regex"></param>
        /// <returns></returns>
        public static bool IsRegexMatch(this string original, string regex)
        {
            return Regex.IsMatch(original, regex);
        }

        public static T ToEnum<T>(this string inString, bool ignoreCase = true, bool throwException = true) where T : struct
        {
            return (T)EnumUtils.ParseEnum<T>(inString, ignoreCase, throwException);
        }
        public static T ToEnum<T>(this string inString, T defaultValue, bool ignoreCase = true, bool throwException = false) where T : struct
        {
            return (T)EnumUtils.ParseEnum<T>(inString, defaultValue, ignoreCase, throwException);
        }
    }
}
